#include "main.h"
#include "io.h"
#include "systick.h"
#include "BSP_Config.h"
#include "gd32f30x_gpio.h"
#include "CAN.h"
#include "ADC.h"
#include "PWM.h"

#include "app_can.h"
#include "app_output.h"
#include "app_input.h"
#include "WDT.h"
#include "flash.h"
#include "usart.h"
#include "radio.h"
#include "lib.h"
#include "param_store.h"
#include "user_tick.h"

/*
状态指示灯：在boot程序中运行，状态指示灯每100ms闪烁一次，快闪；
	       在APP程序中运行，每500ms闪烁一次；
		   在APP程序运行初始30S，快闪，然后每500ms闪烁一次，主要用于测试
*/
uint8_t gStatusLEDFlickerTimeoutSn       = 0;/*状态指示灯闪烁超时标志*/
uint32_t ul_radio_status_led_timeout_cnt = TIME_OUT_500MS;/*状态指示灯闪烁时间*/
/*
错误指示灯：CAN接收通信错误，长亮，同时CAN通信指示灯快速闪烁；
           CAN发送通信错误，不亮，同时CAN通信指示灯快速闪烁
*/


/*
通信指示灯：CAN正常收发，指示灯每250ms闪烁一次；
           CAN收发错误，指示灯每100ms闪烁一次，快闪；
*/
uint8_t uc_can_tx_error_flag = 0;/*发送错误标志*/
uint8_t uc_can_rx_error_flag = 0;/*接收错误标志*/
uint32_t ul_can_rx_error_cnt = 0;/*CAN 接收错误计数*/

uint8_t gSpeedLEDFlickerTimeoutSn = 0;
uint32_t gSpeedLedTimeoutCnt = TIME_OUT_250MS;

void Main_LedCtrl(void)
{
	//CAN 接收错误判断,未收到报文
	if(ul_can_rx_error_cnt > 10) uc_can_rx_error_flag = 1;
	else uc_can_rx_error_flag = 0;
	
	//CAN通信指示灯
	if(gSpeedLEDFlickerTimeoutSn == 1) IO_LedCtrl(xSPEED_LED,LED_ON);
	else IO_LedCtrl(xSPEED_LED,LED_OFF);
	//错误指示灯
	if((uc_can_rx_error_flag == 1) || (uc_can_tx_error_flag == 1)) gSpeedLedTimeoutCnt = TIME_OUT_100MS;
	else gSpeedLedTimeoutCnt = TIME_OUT_250MS;

	if(uc_can_rx_error_flag == 1) IO_LedCtrl(FAULT_LED,LED_ON);
	else IO_LedCtrl(FAULT_LED,LED_OFF);
}


void Main_Sw_Init(void)
{
	uint32_t i = 0;

	hem_config_t default_config;
	memset(&default_config,0x00,sizeof(default_config));

	default_config.config_ok = FLASH_CONFIG_OK;
	default_config.node_id   = NODEID_HEM1604;
	default_config.baudrate  = 250;

#if HEM_AI_NUM > 0
	for (i = 0; i < HEM_AI_NUM; i++)
	{
		default_config.in_mode[i] = IN_MODE_20MA;
	}
	default_config.ai_deadzone  = 10;
	default_config.up_cycle_max = TIME_OUT_2MS;
	default_config.up_cycle_min = TIME_OUT_5MS;
#endif
#if HEM_PWM_NUM > 0
	for(i = 0;i < HEM_PWM_FREQ_NUM;i++)
	{
		default_config.pwm_freq[i] = 200;
	}
#endif
	default_config.err_interval    = 30; // seconds
	default_config.do_timeout_ms   = 500;
	default_config.pwm_timeout_ms  = 500;
	default_config.pwmi_timeout_ms = 500;
	default_config.ao_timeout_ms   = 500;
#if HEM_PWMI_NUM > 0
	default_config.pwmi_kp100 = 63; // 112
	default_config.pwmi_ki100 = 2;	// 48
	default_config.pwmi_kd100 = 2;	// 16
#endif
	node_config_init(&default_config);
	us_set_can_baudrate = g_config.baudrate;

	param_pwmi_data_init();
}
uint8_t uc_feed_watch_dog_timeout_flag = 0;
/**
 * @brief 喂狗函数
 * 
 */
void Main_FeedDog(void)
{
	if (uc_feed_watch_dog_timeout_flag == 0) return;
	uc_feed_watch_dog_timeout_flag = 0;

	WDT_Feed();
}
/**
 * @brief 硬件初始化
 * 
 */
void Main_HW_Init(void)
{
	IO_Init();
	CAN_init();
	PWM_Init(g_config.pwm_freq[0], g_config.pwm_freq[1], g_config.pwm_freq[2], g_config.pwm_freq[3]);
	pwm_sample_calculate(g_config.pwm_freq[2]);
	ADC_Init();
    input_config();
	WDT_Init();

	IO_LedCtrl(xSPEED_LED,LED_OFF);
	IO_LedCtrl(STATUS_LED,LED_OFF);
	IO_LedCtrl(FAULT_LED,LED_OFF);
}
/**
 * @brief BSP运行，把底层需要的运行代码同应用程序区分开
 * 
 */
void bsp_run(void)
{
	Main_LedCtrl();
	param_store_run();
	Main_FeedDog();
	param_store_pwmi_to_flash();
}
int main(void)
{
    SCB->VTOR = FLASH_BASE | APP_LOAD_ADDR_OFFSET;
	systick_config();
	Main_Sw_Init();
	Main_HW_Init();

	while(1)
	{
    	bsp_run();
	}
}
